package com.ht.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ht.entity.*;
import com.ht.modules.system.entity.*;
import com.ht.modules.system.online.config.exception.DBException;
import com.ht.api.ISysBaseAPI;
import com.ht.constant.CommonConstant;
import com.ht.exception.JeecgBootException;
import com.ht.modules.system.mapper.*;
import com.ht.modules.system.service.ISysDictService;
import com.ht.modules.system.service.ISysUserService;
import com.ht.utils.DicConstants;
import com.ht.utils.IPUtils;
import com.ht.utils.SpringContextUtils;
import com.ht.utils.oConvertUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.*;

/**
 *  底层共通业务API，提供其他独立模块调用
 */
@Slf4j
@Service
public class SysBaseApiImpl implements ISysBaseAPI {

	public static final String DB_TYPE_MYSQL="MYSQL";
	public static final String DB_TYPE_ORACLE="ORACLE";
	public static final String DB_TYPE_POSTGRESQL="POSTGRESQL";
	public static final String DB_TYPE_SQLSERVER="SQLSERVER";
	public static String DB_TYPE = "";

	@Resource
	private SysLogMapper sysLogMapper;
	@Autowired
	private SysUserMapper userMapper;
	@Autowired
	private SysUserRoleMapper sysUserRoleMapper;
	@Autowired
	private ISysDictService sysDictService;
	@Resource
	private SysAnnouncementMapper sysAnnouncementMapper;
	@Resource
	private SysAnnouncementSendMapper sysAnnouncementSendMapper;
	@Autowired
	@Lazy
	private ISysUserService sysUserService;
    @Autowired
    private CommonConfigMapper commonConfigMapper;

	@Override
	public void addLog(String LogContent, Integer logType, Integer operatetype) {
		SysLog sysLog = new SysLog();
		// 注解上的描述,操作日志内容
		sysLog.setLogContent(LogContent);
		sysLog.setLogType(logType);
		sysLog.setOperateType(operatetype);
		try {
			// 获取request
			HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
			// 设置IP地址
			sysLog.setIp(IPUtils.getIpAddr(request));
		} catch (Exception e) {
			sysLog.setIp("127.0.0.1");
		}
		// 获取登录用户信息
		LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
		if(sysUser != null){
			sysLog.setUserid(sysUser.getUsername());
			sysLog.setUsername(sysUser.getRealname());
		}
		sysLog.setCreateTime(new Date());
		// 保存系统日志
		sysLogMapper.insert(sysLog);
	}

	@Override
	public LoginUser getUserByName(String username) {
		if(oConvertUtils.isEmpty(username)) {
			return null;
		}
		LoginUser loginUser = new LoginUser();
		SysUser sysUser = userMapper.getUserByName(username);
		if(sysUser == null) {
			return null;
		}
		BeanUtils.copyProperties(sysUser, loginUser);
		return loginUser;
	}

	@Override
	public List<String> getRolesByUsername(String username) {
		return sysUserRoleMapper.getRoleByUserName(username);
	}

	@Override
	public String getDatabaseType() throws SQLException {
		DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class);
		return getDatabaseTypeByDataSource(dataSource);
	}

	@Override
	public String translateDictFromTable(String table, String text, String code, String key) {
		return sysDictService.queryTableDictTextByKey(table, text, code, key);
	}

	@Override
	public String translateDict(String code, String key) {
		return sysDictService.queryDictTextByKey(code, key);
	}


	@Override
	public List<DictModel> queryDictItemsByCode(String code) {
		return sysDictService.queryDictItemsByCode(code);
	}

	@Override
	public List<DictModel> queryTableDictItemsByCode(String table, String text, String code) {
		return sysDictService.queryTableDictItemsByCode(table, text, code);
	}

	@Override
	public Map<String, List<DictModel>> translateManyDict(String dictCodes, String keys) {
		List<String> dictCodeList = Arrays.asList(dictCodes.split(","));
		List<String> values = Arrays.asList(keys.split(","));
		return sysDictService.queryManyDictByKeys(dictCodeList, values);
	}

	@Override
	public List<DictModel> translateDictFromTableByKeys(String table, String text, String code, String keys) {
		return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(",")));
	}

	@Override
	public List<DictModel> queryAllDepartBackDictModel() {
		return sysDictService.queryAllDepartBackDictModel();
	}

	@Override
	public void sendSysAnnouncement(String fromUser, String toUser, String title, String msgContent) {
		SysAnnouncement announcement = new SysAnnouncement();
		announcement.setTitile(title);
		announcement.setMsgContent(msgContent);
		announcement.setSender(fromUser);
		announcement.setPriority(CommonConstant.PRIORITY_M);
		announcement.setMsgType(CommonConstant.MSG_TYPE_USER);
		announcement.setSendStatus(CommonConstant.HAS_SEND);
		announcement.setSendTime(new Date());
		announcement.setMsgCategory("2");
		announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0));
		sysAnnouncementMapper.insert(announcement);
		// 2.插入用户通告阅读标记表记录
        String[] userIds = toUser.split(",");
		String anntId = announcement.getId();
        for (String userId : userIds) {
            if (oConvertUtils.isNotEmpty(userId)) {
                SysUser sysUser = userMapper.getUserByName(userId);
                if (sysUser == null) {
                    continue;
                }
                SysAnnouncementSend announcementSend = new SysAnnouncementSend();
                announcementSend.setAnntId(anntId);
                announcementSend.setUserId(sysUser.getId());
                announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG);
                sysAnnouncementSendMapper.insert(announcementSend);
            }
        }
	}

	/**
	 * 获取数据库类型
	 * @param dataSource
	 * @return
	 * @throws SQLException
	 * @throws DBException
	 */
	private String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{
		if("".equals(DB_TYPE)) {
            try (Connection connection = dataSource.getConnection()) {
                DatabaseMetaData md = connection.getMetaData();
                String dbType = md.getDatabaseProductName().toLowerCase();
                if (dbType.contains("mysql")) {
                    DB_TYPE = DB_TYPE_MYSQL;
                } else if (dbType.contains("oracle")) {
                    DB_TYPE = DB_TYPE_ORACLE;
                } else if (dbType.contains("sqlserver") || dbType.contains("sql server")) {
                    DB_TYPE = DB_TYPE_SQLSERVER;
                } else if (dbType.contains("postgresql")) {
                    DB_TYPE = DB_TYPE_POSTGRESQL;
                } else {
                    throw new JeecgBootException("数据库类型:[" + dbType + "]不识别!");
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
		}
		return DB_TYPE;
	}

	@Override
	public List<DictModel> queryAllDict() {
		// 查询并排序
		QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
		queryWrapper.orderByAsc("create_time");
		List<SysDict> dicts = sysDictService.list(queryWrapper);
		// 封装成 model
		List<DictModel> list = new ArrayList<>();
		for (SysDict dict : dicts) {
			list.add(new DictModel(dict.getDictCode(), dict.getDictName()));
		}
		return list;
	}

	@Override
	public String getRealnameByName(String username) {
		LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, username);
        wrapper.select(SysUser::getRealname);
        SysUser sysUser = sysUserService.getOne(wrapper);
        if(sysUser!=null&&sysUser.getRealname()!=null) {
        	return sysUser.getRealname();
        }
		return null;
	}

    @Override
    public List<String> getCidListByUsername(List<String> usernameList) {
        return 	userMapper.getCidListByUsername(usernameList);
    }

    @Override
    public String getCidByUsername(String username) {
        return userMapper.getCidByUsername(username);
    }

    @Override
    public List<String> getCidListByRoleCode(String roleCode) {
        return userMapper.getCidListByRoleCode(roleCode);
    }

    @Override
    public Map<String, Object> getUniqueConfig() {
        QueryWrapper<CommonConfig> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", DicConstants.DEL_FLAG_WSC);
        List<Map<String, Object>> commonConfigList = commonConfigMapper.selectMaps(wrapper);
        if (commonConfigList == null || commonConfigList.size() <= 0){
            throw new RuntimeException("请检查系统通用配置！");
        }
        return commonConfigList.get(0);
    }

}
